﻿using System;
using System.Collections.Generic;
using Internal.Runtime.Models;
using Runtime.Services.Battle;
using Runtime.Services.Battle.Entity;

namespace Runtime.Models {

    /// <summary>
    /// 效果数据
    /// </summary>
    public interface IDFR_BattleEffectModelTD : IDFR_BattleEffectModelBase {

        new IDFR_BattleEffectModelTDSetter AsSetter();

        new IDFR_BattleSkillModelTD OwnerSkillModel { get; }

        /// <summary>
        /// 目标类型
        /// </summary>
        DFR_BattleEffectTargetType TargetType { get; }

        /// <summary>
        /// 参数列表
        /// </summary>
        IReadOnlyList<F64> ParameterList { get; }

        /// <summary>
        /// 首个参数
        /// </summary>
        F64 FirstParameter { get; }
    }

    public interface IDFR_BattleEffectModelTDSetter : IDFR_BattleEffectModelBaseSetter, IDFR_BattleEffectModelTD {
    }

    public abstract class DFR_BattleEffectModelTD : DFR_BattleEffectModelBase, IDFR_BattleEffectModelTD, IDFR_BattleEffectModelTDSetter, IDFR_BattleEffectModelTDInternal {

        public new IDFR_BattleEffectModelTDSetter AsSetter() => this;

        public DFR_BattleEffectTargetType TargetType { get; protected set; }

        public IReadOnlyList<F64> ParameterList { get; protected set; }

        public F64 FirstParameter => ParameterList[0];

        public override bool IsAttacking => m_Target == DFR_BattleEffectTarget.TargetAttacking || m_Target == DFR_BattleEffectTarget.TargetAttackingNormal;

        public override bool IsPlayer => m_Target == DFR_BattleEffectTarget.Player;

        private DFR_BattleEffectTarget m_Target;

        private bool m_IsForbiddenEliteOrBoss;
        public override bool IsForbiddenEliteOrBoss => m_IsForbiddenEliteOrBoss;

        public new IDFR_BattleSkillModelTD OwnerSkillModel => (IDFR_BattleSkillModelTD)base.OwnerSkillModel;

        protected override void Dispose() {
            ParameterList = null;
            base.Dispose();
        }

        protected void ApplyTarget(DFR_BattleEffectTarget target) {
            m_Target = target;
            switch (target) {
                case DFR_BattleEffectTarget.Player:
                    TargetType = DFR_BattleEffectTargetType.None;
                    RangeType = DFR_BattleEffectRangeType.None;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.None;
                    InfluenceAmount = 0;
                    break;
                case DFR_BattleEffectTarget.TargetAttacking:
                    TargetType = DFR_BattleEffectTargetType.Target;
                    RangeType = DFR_BattleEffectRangeType.SpottingRange;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    InfluenceAmount = 1;
                    break;
                case DFR_BattleEffectTarget.TargetAttackingNormal:
                    TargetType = DFR_BattleEffectTargetType.Target;
                    RangeType = DFR_BattleEffectRangeType.SpottingRange;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    m_IsForbiddenEliteOrBoss = true;
                    InfluenceAmount = 1;
                    break;
                case DFR_BattleEffectTarget.TargetRange:
                    TargetType = DFR_BattleEffectTargetType.Target;
                    RangeType = DFR_BattleEffectRangeType.Range;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    HaloRange = F64.From(OwnerSkillModel.ParameterList[0]);
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[1];
                    break;
                case DFR_BattleEffectTarget.TargetSpottingRange:
                    TargetType = DFR_BattleEffectTargetType.Target;
                    RangeType = DFR_BattleEffectRangeType.SpottingRange;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[0];
                    break;
                case DFR_BattleEffectTarget.TargetAll:
                    TargetType = DFR_BattleEffectTargetType.Target;
                    RangeType = DFR_BattleEffectRangeType.All;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.All;
                    InfluenceAmount = int.MinValue;
                    break;
                case DFR_BattleEffectTarget.SourceRange:
                    TargetType = DFR_BattleEffectTargetType.Source;
                    RangeType = DFR_BattleEffectRangeType.Range;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    HaloRange = F64.From(OwnerSkillModel.ParameterList[0]);
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[1];
                    break;
                case DFR_BattleEffectTarget.SourceSpottingRange:
                    TargetType = DFR_BattleEffectTargetType.Source;
                    RangeType = DFR_BattleEffectRangeType.SpottingRange;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[0];
                    break;
                case DFR_BattleEffectTarget.SourceAll:
                    TargetType = DFR_BattleEffectTargetType.Source;
                    RangeType = DFR_BattleEffectRangeType.All;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.All;
                    InfluenceAmount = int.MinValue;
                    break;
                case DFR_BattleEffectTarget.SourceRandom:
                    TargetType = DFR_BattleEffectTargetType.Source;
                    RangeType = DFR_BattleEffectRangeType.All;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    InfluenceAmount = 1;
                    break;
                case DFR_BattleEffectTarget.RoadRange:
                    TargetType = DFR_BattleEffectTargetType.Road;
                    RangeType = DFR_BattleEffectRangeType.Range;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    HaloRange = F64.From(OwnerSkillModel.ParameterList[0]);
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[1];
                    break;
                case DFR_BattleEffectTarget.RoadSpottingRange:
                    TargetType = DFR_BattleEffectTargetType.Road;
                    RangeType = DFR_BattleEffectRangeType.SpottingRange;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Multiple;
                    InfluenceAmount = (int)OwnerSkillModel.ParameterList[0];
                    break;
                case DFR_BattleEffectTarget.RoadAll:
                    TargetType = DFR_BattleEffectTargetType.Road;
                    RangeType = DFR_BattleEffectRangeType.All;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.All;
                    InfluenceAmount = int.MinValue;
                    break;
                case DFR_BattleEffectTarget.EntitySelf:
                    if (OwnerEntityInstanceID.ID.Type == DFR_BattleEntityType.AttackSource || OwnerEntityInstanceID.ID.Type == DFR_BattleEntityType.Player) {
                        TargetType = DFR_BattleEffectTargetType.Source;
                    } else {
                        throw new NotSupportedException($"未支持的参数，如有需要请联系客户端程序 [{nameof(DFR_BattleEffectTarget)}={target}]");
                    }
                    RangeType = DFR_BattleEffectRangeType.Self;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    InfluenceAmount = 1;
                    break;
                case DFR_BattleEffectTarget.PlatformRandom:
                    TargetType = DFR_BattleEffectTargetType.Platform;
                    RangeType = DFR_BattleEffectRangeType.All;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    InfluenceAmount = 1;
                    break;
                case DFR_BattleEffectTarget.PlatformSelf:
                    TargetType = DFR_BattleEffectTargetType.Platform;
                    RangeType = DFR_BattleEffectRangeType.Self;
                    TargetSelectType = DFR_BattleEffectTargetSelectType.Single;
                    InfluenceAmount = 1;
                    break;

            }
            if (InfluenceAmount == 0) {
                InfluenceAmount = int.MaxValue;
            }
        }

        protected override bool Initialize() {
            return true;
        }
    }
}

namespace Internal.Runtime.Models {

    public interface IDFR_BattleEffectModelTDInternal : IDFR_BattleEffectModelBaseInternal {
    }
}